package task;

import statemap.FSMContext;
import statemap.State;

public class TaskManagerFSM extends FSMContext {

	private static final long serialVersionUID = 1L;

	public TaskManagerFSM(TaskManager owner) {
		super(MainMap.Idle);
		_owner = owner;
	}

	public TaskManagerFSM(TaskManager owner, TaskManagerState initState) {
		super(initState);
		_owner = owner;
	}

	public void enterStartState() {
		getState().Entry(this);
		return;
	}

	public void ReplyTimeout() {
		_transition = "ReplyTimeout";
		getState().ReplyTimeout(this);
		_transition = "";
		return;
	}

	public void RunTask() {
		_transition = "RunTask";
		getState().RunTask(this);
		_transition = "";
		return;
	}

	public void Shutdown() {
		_transition = "Shutdown";
		getState().Shutdown(this);
		_transition = "";
		return;
	}

	public void ShutdownTimeout() {
		_transition = "ShutdownTimeout";
		getState().ShutdownTimeout(this);
		_transition = "";
		return;
	}

	public void SliceTimeout() {
		_transition = "SliceTimeout";
		getState().SliceTimeout(this);
		_transition = "";
		return;
	}

	public void TaskBlocked() {
		_transition = "TaskBlocked";
		getState().TaskBlocked(this);
		_transition = "";
		return;
	}

	public void TaskCreated() {
		_transition = "TaskCreated";
		getState().TaskCreated(this);
		_transition = "";
		return;
	}

	public void TaskDeleted() {
		_transition = "TaskDeleted";
		getState().TaskDeleted(this);
		_transition = "";
		return;
	}

	public void TaskDone() {
		_transition = "TaskDone";
		getState().TaskDone(this);
		_transition = "";
		return;
	}

	public void TaskStopped() {
		_transition = "TaskStopped";
		getState().TaskStopped(this);
		_transition = "";
		return;
	}

	public void TaskSuspended() {
		_transition = "TaskSuspended";
		getState().TaskSuspended(this);
		_transition = "";
		return;
	}

	public void TaskUnblocked() {
		_transition = "TaskUnblocked";
		getState().TaskUnblocked(this);
		_transition = "";
		return;
	}

	public TaskManagerState getState() throws statemap.StateUndefinedException {
		if (_state == null) {
			throw (new statemap.StateUndefinedException());
		}
		return ((TaskManagerState) _state);
	}

	protected TaskManager getOwner() {
		return (_owner);
	}

	public void setOwner(TaskManager owner) {
		if (owner == null) {
			throw (new NullPointerException("null owner"));
		} else {
			_owner = owner;
		}
		return;
	}

	// ---------------------------------------------------------------
	// Member data.
	//

	transient private TaskManager _owner;

	public static abstract class TaskManagerState extends State {

		private static final long serialVersionUID = 1L;

		protected TaskManagerState(String name, int id) {
			super(name, id);
		}

		protected void Entry(TaskManagerFSM context) {
		}

		protected void Exit(TaskManagerFSM context) {
		}

		protected void ReplyTimeout(TaskManagerFSM context) {
			Default(context);
		}

		protected void RunTask(TaskManagerFSM context) {
			Default(context);
		}

		protected void Shutdown(TaskManagerFSM context) {
			Default(context);
		}

		protected void ShutdownTimeout(TaskManagerFSM context) {
			Default(context);
		}

		protected void SliceTimeout(TaskManagerFSM context) {
			Default(context);
		}

		protected void TaskBlocked(TaskManagerFSM context) {
			Default(context);
		}

		protected void TaskCreated(TaskManagerFSM context) {
			Default(context);
		}

		protected void TaskDeleted(TaskManagerFSM context) {
			Default(context);
		}

		protected void TaskDone(TaskManagerFSM context) {
			Default(context);
		}

		protected void TaskStopped(TaskManagerFSM context) {
			Default(context);
		}

		protected void TaskSuspended(TaskManagerFSM context) {
			Default(context);
		}

		protected void TaskUnblocked(TaskManagerFSM context) {
			Default(context);
		}

		protected void Default(TaskManagerFSM context) {
			throw (new statemap.TransitionUndefinedException("State: "
					+ context.getState().getName() + ", Transition: "
					+ context.getTransition()));
		}

		// -----------------------------------------------------------
		// Member data.
		//
	}

	/* package */static abstract class MainMap {
		// -----------------------------------------------------------
		// Member methods.
		//

		// -----------------------------------------------------------
		// Member data.
		//

		// -------------------------------------------------------
		// Constants.
		//
		public static final MainMap_Idle Idle = new MainMap_Idle(
				"MainMap.Idle", 0);
		public static final MainMap_RunningTask RunningTask = new MainMap_RunningTask(
				"MainMap.RunningTask", 1);
		public static final MainMap_SuspendingTask SuspendingTask = new MainMap_SuspendingTask(
				"MainMap.SuspendingTask", 2);
		public static final MainMap_ShuttingDown ShuttingDown = new MainMap_ShuttingDown(
				"MainMap.ShuttingDown", 3);
		public static final MainMap_IdleShutdown IdleShutdown = new MainMap_IdleShutdown(
				"MainMap.IdleShutdown", 4);
		public static final MainMap_ShutdownComplete ShutdownComplete = new MainMap_ShutdownComplete(
				"MainMap.ShutdownComplete", 5);
		private static final MainMap_Default Default = new MainMap_Default(
				"MainMap.Default", -1);

		public static MainMap_Idle getIdle() {
			return Idle;
		}

		public static MainMap_RunningTask getRunningtask() {
			return RunningTask;
		}

		public static MainMap_SuspendingTask getSuspendingtask() {
			return SuspendingTask;
		}

		public static MainMap_ShuttingDown getShuttingdown() {
			return ShuttingDown;
		}

		public static MainMap_IdleShutdown getIdleshutdown() {
			return IdleShutdown;
		}

		public static MainMap_ShutdownComplete getShutdowncomplete() {
			return ShutdownComplete;
		}

		public static MainMap_Default getDefault() {
			return Default;
		}

	}

	protected static class MainMap_Default extends TaskManagerState {

		private static final long serialVersionUID = 1L;

		protected MainMap_Default(String name, int id) {
			super(name, id);
		}

		protected void Shutdown(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(0, "Shutdown started. Stopping all tasks.");
				ctxt.stopAllTimers();
				ctxt.stopAllTasks();
				ctxt.setTimer("ShutdownTimeout", 5000);
			} finally {
				context.setState(MainMap.ShuttingDown);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void TaskCreated(TaskManagerFSM context) {
			return;
		}

		protected void TaskUnblocked(TaskManagerFSM context) {
			return;
		}
	}

	private static final class MainMap_Idle extends MainMap_Default {

		private static final long serialVersionUID = 1L;

		private MainMap_Idle(String name, int id) {
			super(name, id);
		}

		protected void Entry(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			ctxt.sendMessage(4, "Idle. Looking for a task to run.");
			ctxt.checkTaskQueue();
			return;
		}

		protected void RunTask(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.startTask();
			} finally {
				context.setState(MainMap.RunningTask);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void Shutdown(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(0, "Shutdown started.");
				ctxt.setTimer("ShutdownTimeout", 2000);
			} finally {
				context.setState(MainMap.IdleShutdown);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void TaskCreated(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.startTask();
			} finally {
				context.setState(MainMap.RunningTask);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void TaskDone(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			if (ctxt.getRunnableTaskCount() > 0) {

				(context.getState()).Exit(context);
				context.clearState();
				try {
					ctxt.startTask();
				} finally {
					context.setState(MainMap.RunningTask);
					(context.getState()).Entry(context);
				}
			} else {
				TaskManagerState endState = context.getState();

				context.clearState();
				try {
					ctxt.stopTimer("ReplyTimeout");
				} finally {
					context.setState(endState);
				}
			}
			return;
		}

		protected void TaskUnblocked(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.startTask();
			} finally {
				context.setState(MainMap.RunningTask);
				(context.getState()).Entry(context);
			}
			return;
		}
	}

	private static final class MainMap_RunningTask extends MainMap_Default {

		private static final long serialVersionUID = 1L;

		private MainMap_RunningTask(String name, int id) {
			super(name, id);
		}

		protected void Entry(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			ctxt.setTimer("Slice Timeout", 3000);
			return;
		}

		protected void Exit(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			ctxt.stopTimer("Slice Timeout");
			return;
		}

		protected void SliceTimeout(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.suspendTask();
			} finally {
				context.setState(MainMap.SuspendingTask);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void TaskBlocked(TaskManagerFSM context) {

			(context.getState()).Exit(context);
			context.setState(MainMap.Idle);
			(context.getState()).Entry(context);
			return;
		}

		protected void TaskDeleted(TaskManagerFSM context) {

			(context.getState()).Exit(context);
			context.setState(MainMap.Idle);
			(context.getState()).Entry(context);
			return;
		}

		protected void TaskDone(TaskManagerFSM context) {

			(context.getState()).Exit(context);
			context.setState(MainMap.Idle);
			(context.getState()).Entry(context);
			return;
		}

		protected void TaskSuspended(TaskManagerFSM context) {

			(context.getState()).Exit(context);
			context.setState(MainMap.Idle);
			(context.getState()).Entry(context);
			return;
		}
	}

	private static final class MainMap_SuspendingTask extends MainMap_Default {

		private static final long serialVersionUID = 1L;

		private MainMap_SuspendingTask(String name, int id) {
			super(name, id);
		}

		protected void Entry(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			ctxt.setTimer("Reply Timeout", 500);
			return;
		}

		protected void Exit(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			ctxt.stopTimer("Reply Timeout");
			return;
		}

		protected void ReplyTimeout(TaskManagerFSM context) {

			(context.getState()).Exit(context);
			context.setState(MainMap.Idle);
			(context.getState()).Entry(context);
			return;
		}

		protected void TaskDone(TaskManagerFSM context) {

			(context.getState()).Exit(context);
			context.setState(MainMap.Idle);
			(context.getState()).Entry(context);
			return;
		}

		protected void TaskSuspended(TaskManagerFSM context) {

			(context.getState()).Exit(context);
			context.setState(MainMap.Idle);
			(context.getState()).Entry(context);
			return;
		}
	}

	private static final class MainMap_ShuttingDown extends MainMap_Default {

		private static final long serialVersionUID = 1L;

		private MainMap_ShuttingDown(String name, int id) {
			super(name, id);
		}

		protected void Shutdown(TaskManagerFSM context) {
			return;
		}

		protected void ShutdownTimeout(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(0,
						"Timed out waiting for tasks to stop. Forcibly deleting tasks and exiting.");
				ctxt.deleteAllTasks();
				ctxt.exitApplication();
			} finally {
				context.setState(MainMap.ShutdownComplete);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void TaskStopped(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			if (ctxt.getRunningTask() == null
					&& ctxt.getRunnableTaskCount() == 0
					&& ctxt.getBlockedTaskCount() == 0) {

				(context.getState()).Exit(context);
				context.clearState();
				try {
					ctxt.stopTimer("ShutdownTimeout");
					ctxt.sendMessage(0, "Shutdown completed.");
					ctxt.exitApplication();
				} finally {
					context.setState(MainMap.ShutdownComplete);
					(context.getState()).Entry(context);
				}
			} else {
			}
			return;
		}

		protected void TaskSuspended(TaskManagerFSM context) {
			return;
		}
	}

	private static final class MainMap_IdleShutdown extends MainMap_Default {

		private static final long serialVersionUID = 1L;

		private MainMap_IdleShutdown(String name, int id) {
			super(name, id);
		}

		protected void Default(TaskManagerFSM context) {
			return;
		}

		protected void ShutdownTimeout(TaskManagerFSM context) {
			TaskManager ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(0, "Shutdown completed.");
				ctxt.exitApplication();
			} finally {
				context.setState(MainMap.ShutdownComplete);
				(context.getState()).Entry(context);
			}
			return;
		}
	}

	private static final class MainMap_ShutdownComplete extends MainMap_Default {

		private static final long serialVersionUID = 1L;

		private MainMap_ShutdownComplete(String name, int id) {
			super(name, id);
		}

		protected void Default(TaskManagerFSM context) {
			return;
		}

		protected void Shutdown(TaskManagerFSM context) {
			return;
		}
	}
}